<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style>
    .cont{margin: 0 auto;position: relative;}
    .cont .box{padding: 5px;float: left;}
    .cont .box .imgbox{border: solid 1px black;border-radius:4px;padding: 6px;}
    .cont .box .imgbox img{width: 200px;}
    .cont .box h3{width: 200px;}
  </style>
</head>
<body>
  <div class="cont">
  </div>
</body>
<script src="./data.js"></script>
<script>
  const cont = document.querySelector(".cont");
  
  // 遍历数据，拼接字符形式的页面结构
  let str = "";
  data.forEach(val=>{
    str += `<div class="box">
              <div class="imgbox"><img src="${val.img}" alt=""></div>
              <h3>${val.title}</h3>
            </div>`
  })
  // 设置到指定容器
  cont.innerHTML = str;

  // ======

  // 数据获取成功，且页面拼接完成，渲染结束后，才能拿到box
  const box = document.querySelectorAll(".cont .box");
  // 获取显示器宽度
  const clientW = document.documentElement.clientWidth;
  // 获取任意一列的列宽
  const boxW = box[0].offsetWidth;
  // 计算一行最多放几列
  const maxNum = Math.floor(clientW / boxW);
  // 根据最大列数计算容器宽度（居中）
  cont.style.width = maxNum * boxW + "px";
  // 加载完成后
  onload = function(){
    // 准备存放所有列高
    const heightArr = [];
    // 遍历第一行元素，获取高度，作为初始列高
    for(let i=0;i<maxNum;i++){
      heightArr.push(box[i].offsetHeight);
    }
    // 遍历其他所有元素，准备设置定位和位置
    for(let j=maxNum;j<box.length;j++){
      // 添加定位
      box[j].style.position = "absolute";
      // 获取最小列高
      const min = Math.min(...heightArr);
      // 获取最小列高的索引
      const minIndex = heightArr.indexOf( min );
      // 将最小列表设置为当前元素的top
      box[j].style.top = min + "px";
      // 根据最小列高的索引，计算当前元素的left
      box[j].style.left = minIndex * boxW + "px";
      // 将当前元素的高度，累加到当前列高中
      heightArr[minIndex] += box[j].offsetHeight;
    }
  }



</script>
</html>